package com.lninl.config;

import com.lninl.model.IdEntity;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.hibernate4.HibernateExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaDialect;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.inject.Inject;
import javax.persistence.EntityManagerFactory;
import java.net.URISyntaxException;
import java.util.Properties;

@Configuration
@EnableJpaRepositories("com.lninl")
@EnableTransactionManagement
// @EnableCaching
@PropertySource("classpath:config.properties")
public class BusinessConfiguration {

    @Inject
    Environment env;

    @Bean
    public DataSource dataSource() {
        final DataSource dataSource = new DataSource();
        dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
        dataSource.setUrl(env.getProperty("jdbc.url"));
        dataSource.setUsername(env.getProperty("jdbc.username"));
        dataSource.setPassword(env.getProperty("jdbc.password"));
        dataSource.setDefaultAutoCommit(env.getProperty(
                "jdbc.defaultAutoCommit", Boolean.class));
        dataSource.setMaxActive(env.getProperty("jdbc.pool.maxActive", Integer.class));
        dataSource.setMaxIdle(env.getProperty("jdbc.pool.maxIdle", Integer.class));
        dataSource.setMinIdle(0);
        dataSource.setDefaultAutoCommit(false);

        //连接Idle10分钟后超时，每1分钟检查一次
        dataSource.setTimeBetweenEvictionRunsMillis(60000);
        dataSource.setMinEvictableIdleTimeMillis(600000);
        return dataSource;
    }

    @Bean
    public EntityManagerFactory entityManagerFactory()
            throws URISyntaxException {
        LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactory.setDataSource(dataSource());
        entityManagerFactory.setPackagesToScan(IdEntity.class.getPackage().getName());
        entityManagerFactory.setPersistenceUnitName("lninl");
        entityManagerFactory.setJpaProperties(jpaProperties());
        entityManagerFactory.setJpaVendorAdapter(hibernateJpaVendorAdapter());
        entityManagerFactory.afterPropertiesSet();
        return entityManagerFactory.getObject();
    }

    private HibernateJpaVendorAdapter hibernateJpaVendorAdapter() {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setShowSql(env.getProperty("jpa.showSql", Boolean.class));
        vendorAdapter.setDatabase(env.getProperty("jpa.database", Database.class));
        vendorAdapter.setGenerateDdl(env.getProperty("jpa.generateDdl", Boolean.class));
        return vendorAdapter;
    }

    Properties jpaProperties(){
        Properties properties = new Properties();
        properties.put("hibernate.cache.region.factory_class","org.hibernate.cache.ehcache.EhCacheRegionFactory");
        properties.put("net.sf.ehcache.configurationResourceName","ehcache.xml");
        properties.put("hibernate.ejb.naming_strategy","org.hibernate.cfg.ImprovedNamingStrategy");
        return properties;
    }

    @Bean
    public PlatformTransactionManager transactionManager()
            throws URISyntaxException {
        JpaTransactionManager transactionManager = new JpaTransactionManager(
                entityManagerFactory());
        transactionManager.setDataSource(dataSource());
        transactionManager.setJpaDialect(new HibernateJpaDialect());
        return transactionManager;
    }

    @Bean
    public HibernateExceptionTranslator hibernateExceptionTranslator() {
        return new HibernateExceptionTranslator();
    }
}
